#include "tcp.h"

// 被动套接字的初始化
int tcpInit(const char *ip, unsigned short port) 
{
    // 建立主动套接字
    int listenfd = socket(AF_INET, SOCK_STREAM, 0);
    ERROR_CHECK(listenfd, -1, "socket");
    // 设定套接字属性
    int on = 1;
    int ret = setsockopt(listenfd, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on));
    ERROR_CHECK(ret, -1, "setsockopt addr");
    ret = setsockopt(listenfd, SOL_SOCKET, SO_REUSEPORT, &on, sizeof(on));
    ERROR_CHECK(ret, -1, "setsockopt port");
    // 使用bind函数绑定网络信息
    //
    // 设置结构体struct sockadd_in
    struct sockaddr_in serveraddr;
    serveraddr.sin_family = AF_INET;
    serveraddr.sin_addr.s_addr = inet_addr(ip);
    serveraddr.sin_port = htons(port);
    // 使用bind
    ret = bind(listenfd, (struct sockaddr *)&serveraddr,sizeof(serveraddr));
    ERROR_CHECK(ret, -1, "bind");
    //
    // 将主动套接字改为被动套接字
    ret = listen(listenfd, 10);
    ERROR_CHECK(ret, -1, "listen");

    return listenfd;
}

// 添加epoll监听的读事件
void epollAddReadEvent(int epfd, int readfd)
{
    // 使用eoll_ctl前的准备
    // 设置struct epoll_event结构体
    struct epoll_event event;
    event.events = EPOLLIN;// 监听读事件
    event.data.fd = readfd;// 将监听套接字fd加入用户数据中，读事件就绪时原样返回
    // 调用函数epoll_ctl函数监听套接字
    int ret = epoll_ctl(epfd, EPOLL_CTL_ADD, readfd, &event);
    ERROR_CHECK(ret, -1, "epoll_ctl");
}

// 删除epoll中监听的事件
void epollDelEvent(int epfd, int fd)
{
    // 设置事件的epoll_event结构体
    struct epoll_event event;
    // event.events = EPOLLIN;//可以不用设置是否是读事件 
    event.data.fd = fd; 
    int ret = epoll_ctl(epfd, EPOLL_CTL_DEL, fd, &event);
    ERROR_CHECK(ret, -1, "epoll_ctl del");
}


